#include "ll_i2c.h"
#include "ll_exti.h"
#include "ll_gpio.h"
#include "stdio.h"

/*****************************************************
Tabel I2C-Pin about stm32f407 gpio alternate for I2C
┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━┓
┃   function    ┃   pin     ┃  pin      ┃   pin     ┃
┠━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┨
┃   I2C1_SCL    ┃   PB6     ┃  PB8      ┃           ┃
┃   I2C1_SDA    ┃   PB7     ┃  PB9      ┃           ┃
┠━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┨
┃   I2C2_SCL    ┃   PB10    ┃  PF1      ┃   PH4     ┃
┃   I2C2_SDA    ┃   PB11    ┃  PF0      ┃   PH5     ┃
┠━━━━━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┼━━━━━━━━━━━┨
┃   I2C3_SCL    ┃   PA8     ┃  PH7      ┃           ┃
┃   I2C3_SDA    ┃   PC9     ┃  PH8      ┃           ┃
┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┛
*****************************************************/
/*
    LL_I2C_IsActiveFlag_SB(I2C_TypeDef *I2Cx);
    LL_I2C_IsActiveFlag_ADDR(I2C_TypeDef *I2Cx);
    LL_I2C_IsActiveFlag_BTF(I2C_TypeDef *I2Cx);
    LL_I2C_IsActiveFlag_BUSY(I2C_TypeDef *I2Cx);
    LL_I2C_IsActiveFlag_MSL(I2C_TypeDef *I2Cx);
    LL_I2C_GenerateStartCondition(I2C_TypeDef *I2Cx);
    LL_I2C_GenerateStopCondition(I2C_TypeDef *I2Cx);
    LL_I2C_TransmitData8(I2C_TypeDef *I2Cx, uint8_t Data);
    LL_I2C_IsActiveFlag_RXNE(I2C_TypeDef *I2Cx);
    LL_I2C_IsActiveFlag_TXE(I2C_TypeDef *I2Cx);
    LL_I2C_AcknowledgeNextData(I2C_TypeDef *I2Cx, uint32_t TypeAcknowledge);
 */

/* 在下面的数组中配置I2C使用的引脚id,这里使用了IOTGPIO驱动 */
static uint16_t g_i2cPinMap[I2C_MAX][2] = {
    {I2C1_SCL, I2C1_SDA},
    {I2C2_SCL, I2C2_SDA},
    {I2C3_SCL, I2C3_SDA},
};

I2C_Config g_i2cConfig[I2C_MAX]={0};
extern Pin_ST g_pinsGroup[STM32_GPIO_GROUP_MAX*STM32_GPIO_PIN_MAX];

I2C_TypeDef *LL_GET_I2Cx(uint8_t id)
{
    switch(id)
    {
        case 1: return I2C1;
        case 2: return I2C2;
        case 3: return I2C3;
    }
}

uint8_t LL_I2C_PIN_CONFIG(uint8_t id)
{   
    g_i2cConfig[id-1].I2Cx = LL_GET_I2Cx(id);
    // 设置引脚号
    g_i2cConfig[id-1].scl = g_i2cPinMap[id-1][0];
    g_i2cConfig[id-1].sda = g_i2cPinMap[id-1][1];

    // 配置引脚参数
    LL_CONFIG_GPIO(g_i2cConfig[id-1].scl, LL_GPIO_MODE_ALTERNATE, LL_GPIO_PULL_NO, LL_GPIO_SPEED_FREQ_VERY_HIGH, LL_GPIO_OUTPUT_OPENDRAIN, LL_GPIO_AF_4);
    LL_CONFIG_GPIO(g_i2cConfig[id-1].sda, LL_GPIO_MODE_ALTERNATE, LL_GPIO_PULL_NO, LL_GPIO_SPEED_FREQ_VERY_HIGH, LL_GPIO_OUTPUT_OPENDRAIN, LL_GPIO_AF_4);
    /************************* 初始化 SCL引脚 ******************************/
    STM32_GPIO_GROUP group = (g_i2cConfig[id-1].scl)/16;
    // 打开时钟
    LL_AHB1_GRP1_EnableClock(LL_GET_GPIO_CLK(group));
    GPIO_TypeDef *GPIOx = LL_GET_GPIOX((group));
    // 初始化引脚
    if(LL_GPIO_Init(GPIOx, &g_pinsGroup[g_i2cConfig[id-1].scl].gpioInitStruct) != SUCCESS)
    {
        printf("%s line %d error : LL_GPIO_Init I2C SCL pin failed...\n", __func__, __LINE__);
        return ERROR;
    }
    /************************* 初始化 SDA引脚 ******************************/
    // 改变引脚编号，其余参数一样
    group = (g_i2cConfig[id-1].sda)/16;
    // 打开时钟
    LL_AHB1_GRP1_EnableClock(LL_GET_GPIO_CLK(group));
    GPIOx = LL_GET_GPIOX((group));
    // 初始化引脚
    if(LL_GPIO_Init(GPIOx, &g_pinsGroup[g_i2cConfig[id-1].sda].gpioInitStruct) != SUCCESS)
    {
        printf("%s line %d error : LL_GPIO_Init I2C SDA pin failed...\n", __func__, __LINE__);
        return ERROR;
    }
    return SUCCESS;
}

uint32_t LL_GET_I2C_CLK(uint8_t id)
{
    switch (id)
    {
    case 1: return LL_APB1_GRP1_PERIPH_I2C1;
    case 2: return LL_APB1_GRP1_PERIPH_I2C2;
    case 3: return LL_APB1_GRP1_PERIPH_I2C3;
    default:
        return 0;
    }
}